#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "LineAnalyzer.h"
#include "LinkedList.h"
#include "StringExtension.h"
#include "FileHelper.h"

#define OBJ_FILE_EXTENSION ".obj" /* obj file extension */
#define EXTERNAL_FILE_EXTENSION ".ext" /* file extension */
#define ENTRY_FILE_EXTENSION ".ent" /* Legal file entry */

char origFilePath[MAX_PATH_LENGTH];			/* File path */
BOOL isEntryFileOpened;						/* Is the entry file was opened */
BOOL isExternFileOpened;					/* Is the external file was opened */
BOOL isObjFileOpened;						/* Is the obj file was opened */


/*********************************************************************************************************************** */
/* Description: Clear the file
/* Input: filePath - file path that we want to clear
/* Input: isFileOpened - Check if the file was opened and only then clear the file
/* Input: forceWrite - Force clear of the file no matter if the file was opened or not
/*********************************************************************************************************************** */
void clearFile(char* filePath, BOOL* isFileOpened, BOOL forceWrite)
{
	/* Clear the file if it is not opened before */
	if (!*isFileOpened || forceWrite)
	{
		*isFileOpened = TRUE;
		FILE *file = fopen((const char*)filePath , WRITE_MODE);
		fclose(file);
	}
}

/*********************************************************************************************************************** */
/* Description: Clear the entry file
/*********************************************************************************************************************** */
void clearEntryFile()
{
	char fullFileEntries[MAX_PATH_LENGTH];		/* Entry file path */

	/* Add ".ent" extension to the file path */
	strcpy(fullFileEntries, origFilePath);
	strcat(fullFileEntries,ENTRY_FILE_EXTENSION);

	/* Clear the file if it is not opened before */
	clearFile(fullFileEntries, &isEntryFileOpened, TRUE);
}

/*********************************************************************************************************************** */
/* Description: Clear the external file
/*********************************************************************************************************************** */
void clearExternalFile()
{
	char fullFileExternal[MAX_PATH_LENGTH];		/* External file path */
	
	/* Add ".ext" extension to the file path */
	strcpy(fullFileExternal, origFilePath);
	strcat(fullFileExternal,EXTERNAL_FILE_EXTENSION);

	/* Clear the file if it is not opened before */
	clearFile(fullFileExternal, &isExternFileOpened, TRUE);
}

/*********************************************************************************************************************** */
/* Description: Clear the obj file
/*********************************************************************************************************************** */
void clearObjFile()
{
	char fullFileObj[MAX_PATH_LENGTH];		/* Entry file path */

	/* Add ".ent" extension to the file path */
	strcpy(fullFileObj, origFilePath);
	strcat(fullFileObj,OBJ_FILE_EXTENSION);

	/* Clear the file if it is not opened before */
	clearFile(fullFileObj, &isObjFileOpened, TRUE);
}

/*********************************************************************************************************************** */
/* Description: Print a line in the entry file
/* Input: label - label that entry uses - it should be printed 
/* Input: counter - line number of the label
/*********************************************************************************************************************** */
void printEntry( char* label, int counter)
{
	char fullFileEntries[MAX_PATH_LENGTH];		/* Entry file path */

	/* Add ".ent" extension to the file path */
	strcpy(fullFileEntries, origFilePath);
	strcat(fullFileEntries,ENTRY_FILE_EXTENSION);

	/* Clear the file if it is not opened before */
	clearFile(fullFileEntries, &isEntryFileOpened, FALSE);
	
	/* Open the file for append and print */

	FILE *file = fopen((const char*)fullFileEntries , APPEND_MODE);

	fprintf(file,"%s %o\n",label, counter);

	fclose(file);
}

/*********************************************************************************************************************** */
/* Description: Print a line in the external file
/* Input: label - label of the extern aluses - it should be printed 
/* Input: counter - line number of the command that uses this external label
/*********************************************************************************************************************** */
void printExternal(char* label, int counter)
{
	char fullFileExternal[MAX_PATH_LENGTH];		/* External file path */
	
	/* Add ".ext" extension to the file path */
	strcpy(fullFileExternal, origFilePath);
	strcat(fullFileExternal,EXTERNAL_FILE_EXTENSION);

	/* Clear the file if it is not opened before */
	clearFile(fullFileExternal, &isExternFileOpened, FALSE);
	
	/* Open the file for append and print */

	FILE *file = fopen((const char*)fullFileExternal , APPEND_MODE);

	fprintf(file,"%s %o\n",label, counter);

	fclose(file);
}

/*********************************************************************************************************************** */
/* Description: Print a line in the obj file
/* Input: address - address of the line
/* Input: data - numeric data that represents the current line
/* Input: are - Absolute / Rellocatable / External
/*********************************************************************************************************************** */
void printObj(int address, int data, char are)
{
	char fullFileObj[MAX_PATH_LENGTH];			/* Obj file path */

	/* Add ".obj" extension to the file path */
	strcpy(fullFileObj, origFilePath);
	strcat(fullFileObj, OBJ_FILE_EXTENSION);

	/* Clear the file if it is not opened before */
	clearFile(fullFileObj, &isObjFileOpened, FALSE);
	
	/* Open the file for append and print */

	FILE *file = fopen((const char*)fullFileObj , APPEND_MODE);

	fprintf(file,"%o\t%o\t%c\n",address, data, are);

	fclose(file);
}

/*********************************************************************************************************************** */
/* Description: Print the header of the obj file
/* Input: ic - tottal of code lines
/* Input: dc - total of data lines
/*********************************************************************************************************************** */
void printObjHeader(int ic, int dc)
{
	char fullFileObj[MAX_PATH_LENGTH];			/* Obj file path */

	/* Add ".obj" extension to the file path */
	strcpy(fullFileObj, origFilePath);
	strcat(fullFileObj, OBJ_FILE_EXTENSION);

	/* Clear the file if it is not opened before */
	clearFile(fullFileObj, &isObjFileOpened, FALSE);

	/* Open the file for append and print */

	FILE *file = fopen((const char*)fullFileObj , APPEND_MODE);

	fprintf(file,"%o\t%o\n",ic, dc);

	fclose(file);
}